#include <cstdlib>
#include <iostream>
#include <iomanip>
#include <sstream>


#include "Chessboard.h"
#include "LightException.h"
#include "Library.h"

using namespace std;

Chessboard::Chessboard(int width, int height) {
    this->init(width, height);
}

Chessboard::Chessboard(int width, int height, int* coordinates, int q) {
    this->init(width, height);

    // inicializace zaplých světel
    for (int i = 0; i < (2 * q); i += 2) {
        this->switchState(coordinates[i], coordinates[i + 1]);
    }
}

Chessboard::~Chessboard() {
    delete this->m_data;
}

void Chessboard::pressLight(int x, int y) {
    int px = x;
    int py = y;
    Chessboard::switchState(px, py);

    if (px - 1 >= 0) Chessboard::switchState(px - 1, py);
    if (py - 1 >= 0) Chessboard::switchState(px, py - 1);
    if (px + 1 < m_width) Chessboard::switchState(px + 1, py);
    if (py + 1 < m_height) Chessboard::switchState(px, py + 1);

}

//void Chessboard::pressLight(int fieldNumber) {
//    int x = fieldNumber % m_width;
//    int y = fieldNumber / m_width;
//    this->pressLight(x, y);
//}

int Chessboard::getOnLightsCount() const {
    return this->m_onLightsCount;
}

int Chessboard::getSize() const {
    return this->m_width * this->m_height;
}

//============================ PRIVATE METHODS =================================

void Chessboard::init(int width, int height) {
    if (width < 3 || height < 3) throw new LightException("Width and Height must be at least 3!");
    this->m_width = width;
    this->m_height = height;
    this->m_onLightsCount = 0;
    this->m_data = new bool[m_width * m_height];
    for (int i = 0; i < m_width * m_height; i++) {
        this->m_data[i] = false;
    }
}

void Chessboard::switchState(int x, int y) {
    bool* field = this->getField(x, y);

    if (*field) {
        *field = false;
        m_onLightsCount--;
    } else {
        *field = true;
        m_onLightsCount++;
    }
}

bool* Chessboard::getField(int x, int y) {
    this->verifyCoords(x, y);
    return &(this->m_data[Library::getCoordLength(m_width, x, y)]);
}

void Chessboard::verifyCoords(int x, int y) const {
    if (x < 0 || y < 0 || x >= m_width || x >= m_height) {
        throw new LightException("Bad Coordinates!");
    }
}




